#include "connectfour.h"
#include <gtest/gtest.h>

using namespace CS270Game;


TEST(CFBOARD, constructor_and_size) {
  ConnectFour::CFBoard board;
  //Verify that, when constructed, the board reports the expected
  //number of rows and columns
  //
  //Wait, this test fails as it is?  Why is that?  
  //FIXME
  EXPECT_EQ(CFBOARDSIZE_Y, board.numRows());
  EXPECT_EQ(CFBOARDSIZE_X, board.numCols());
}

TEST(CFBOARD, isFull) {
  ConnectFour::CFBoard board;

  //Fill the board everywhere except the top row
  for (int i = 0; i < board.numRows()-1; i++) {
    for (int j = 0; j < board.numCols(); j++) {
      board[i][j] = ConnectFour::RED;
    }
    //The board should not be full at any point
    EXPECT_FALSE(board.isFull());
  }
  //Make one of the rows completely full: still not completely full
  board[board.numRows()-1][board.numCols()-1] = ConnectFour::RED;
  EXPECT_FALSE(board.isFull());
  //Fill the entire top row: now the board should actually be full
  for (int i = 0; i < board.numCols(); i++) {
    board[board.numRows()-1][i] = ConnectFour::RED;
  }
  EXPECT_TRUE(board.isFull());
}

//test isWin(...) 
TEST(CFBOARD, isWin) {
  {
    ConnectFour::CFBoard board;
    board[0][0] = ConnectFour::RED;
    board[0][1] = ConnectFour::RED;
    board[0][2] = ConnectFour::RED;
    
    board[1][0] = ConnectFour::BLACK;
    board[2][1] = ConnectFour::BLACK;
    board[3][2] = ConnectFour::BLACK;
    EXPECT_EQ(board.isWin(),-1);
    board[4][3] = ConnectFour::BLACK;
    EXPECT_TRUE(board.isWin());
    EXPECT_EQ(board.isWin(), ConnectFour::BLACK);
  }
  {
    ConnectFour::CFBoard board;
    board[0][0] = ConnectFour::RED;
    board[0][1] = ConnectFour::RED;
    board[0][2] = ConnectFour::RED;
    
    board[1][0] = ConnectFour::BLACK;
    board[1][1] = ConnectFour::BLACK;
    board[1][2] = ConnectFour::BLACK;
    EXPECT_EQ(board.isWin(),-1);
    board[0][3] = ConnectFour::RED;
    EXPECT_TRUE(board.isWin());
    EXPECT_EQ(board.isWin(), ConnectFour::RED);
  }
  {
    ConnectFour::CFBoard board;
    board[0][0] = ConnectFour::RED;
    board[0][1] = ConnectFour::RED;
    board[0][2] = ConnectFour::RED;
    
    board[5][0] = ConnectFour::BLACK;
    board[4][1] = ConnectFour::BLACK;
    board[3][2] = ConnectFour::BLACK;
    EXPECT_EQ(board.isWin(),-1);
    board[2][3] = ConnectFour::BLACK;
    EXPECT_EQ(board.isWin(), ConnectFour::BLACK);
  }
  {
    ConnectFour::CFBoard board;
    board[0][0] = ConnectFour::RED;
    board[0][1] = ConnectFour::RED;
    board[0][2] = ConnectFour::RED;
    
    board[5][0] = ConnectFour::BLACK;
    board[4][0] = ConnectFour::BLACK;
    board[3][0] = ConnectFour::BLACK;
    EXPECT_EQ(board.isWin(),-1);
    board[2][0] = ConnectFour::BLACK;
    EXPECT_TRUE(board.isWin());
    EXPECT_EQ(board.isWin(), ConnectFour::BLACK);
  }
}

//test makeMove(...)
TEST(CFBOARD, makeMove) {
  {
    ConnectFour::CFBoard board;
    EXPECT_FALSE(board.makeMove(-1, ConnectFour::RED));
    EXPECT_FALSE(board.makeMove(board.numCols(), ConnectFour::RED));
    EXPECT_FALSE(board.makeMove(board.numCols()+1, ConnectFour::RED));
    EXPECT_TRUE(board.makeMove(0, ConnectFour::RED));
    EXPECT_TRUE(board.makeMove(0, ConnectFour::RED));
    EXPECT_TRUE(board.makeMove(0, ConnectFour::RED));
    EXPECT_TRUE(board.makeMove(0, ConnectFour::RED));
    EXPECT_TRUE(board.makeMove(0, ConnectFour::RED));
    EXPECT_TRUE(board.makeMove(0, ConnectFour::RED));
    EXPECT_FALSE(board.makeMove(0, ConnectFour::RED));
  }
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
